home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / lib / xulrunner-1.9.0.14 / chrome / toolkit.jar / content / global / bindings / tabbox.xml < prev    next >
Encoding:
Extensible Markup Language  |  2008-03-05  |  22.8 KB  |  734 lines

  1. <?xml version="1.0"?>
  2.  
  3. <!DOCTYPE bindings [
  4.   <!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd">
  5.   %globalDTD;
  6. ]>
  7.  
  8. <bindings id="tabBindings"
  9.           xmlns="http://www.mozilla.org/xbl"
  10.           xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
  11.           xmlns:xbl="http://www.mozilla.org/xbl">
  12.  
  13.   <binding id="tab-base">
  14.     <resources>
  15.       <stylesheet src="chrome://global/skin/tabbox.css"/>
  16.     </resources>
  17.   </binding>
  18.  
  19.   <binding id="tabbox"
  20.            extends="chrome://global/content/bindings/tabbox.xml#tab-base">
  21.     <implementation implements="nsIDOMEventListener, nsIAccessibleProvider">
  22.       <property name="accessibleType" readonly="true">
  23.         <getter>
  24.           <![CDATA[
  25.             return Components.interfaces.nsIAccessibleProvider.XULTabBox;
  26.           ]]>
  27.         </getter>
  28.       </property>
  29.  
  30.       <property name="handleCtrlTab">
  31.         <setter>
  32.         <![CDATA[
  33.           this.setAttribute("handleCtrlTab", val);
  34.           return val;
  35.         ]]>
  36.         </setter>
  37.         <getter>
  38.         <![CDATA[
  39.           return (this.getAttribute("handleCtrlTab") != "false");
  40.         ]]>
  41.         </getter>
  42.       </property>
  43.       
  44.       <property name="handleCtrlPageUpDown">
  45.         <setter>
  46.         <![CDATA[
  47.           this.setAttribute("handleCtrlPageUpDown", val);
  48.           return val;
  49.         ]]>
  50.         </setter>
  51.         <getter>
  52.         <![CDATA[
  53.           return (this.getAttribute("handleCtrlPageUpDown") != "false");
  54.         ]]>
  55.         </getter>
  56.       </property>
  57.  
  58.       <field name="_handleMetaAltArrows" readonly="true">
  59.         false
  60.       </field>
  61.  
  62.       <!-- _tabs and _tabpanels are deprecated , there are here for
  63.            backwards compatibility, -->
  64.       <property name="_tabs" readonly="true" onget="return this.tabs;"/>
  65.       <property name="_tabpanels" readonly="true" onget="return this.tabpanels;"/>
  66.  
  67.       <property name="tabs" readonly="true">
  68.         <getter>
  69.         <![CDATA[
  70.           return this.getElementsByTagNameNS(
  71.               "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
  72.               "tabs").item(0);
  73.         ]]>
  74.         </getter>
  75.       </property>
  76.  
  77.       <property name="tabpanels" readonly="true">
  78.         <getter>
  79.         <![CDATA[
  80.           return this.getElementsByTagNameNS(
  81.               "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
  82.               "tabpanels").item(0);
  83.         ]]>
  84.         </getter>
  85.       </property>
  86.       
  87.       <property name="selectedIndex">
  88.         <getter>
  89.         <![CDATA[
  90.           var tabs = this.tabs;
  91.           return tabs ? tabs.selectedIndex : -1;
  92.         ]]>
  93.         </getter>
  94.  
  95.         <setter>
  96.         <![CDATA[
  97.           var tabs = this.tabs;
  98.           if (tabs)
  99.             tabs.selectedIndex = val;
  100.           this.setAttribute("selectedIndex", val);
  101.           return val;
  102.         ]]>
  103.         </setter>
  104.       </property>
  105.  
  106.       <property name="selectedTab">
  107.         <getter>
  108.         <![CDATA[
  109.           var tabs = this.tabs;
  110.           return tabs && tabs.selectedItem;
  111.         ]]>
  112.         </getter>
  113.  
  114.         <setter>
  115.         <![CDATA[
  116.           if (val) {
  117.             var tabs = this.tabs;
  118.             if (tabs)
  119.               tabs.selectedItem = val;
  120.           }
  121.           return val;
  122.         ]]>
  123.         </setter>
  124.       </property>
  125.  
  126.       <property name="selectedPanel">
  127.         <getter>
  128.         <![CDATA[
  129.           var tabpanels = this.tabpanels;
  130.           return tabpanels && tabpanels.selectedPanel;
  131.         ]]>
  132.         </getter>
  133.  
  134.         <setter>
  135.         <![CDATA[
  136.           if (val) {
  137.             var tabpanels = this.tabpanels;
  138.             if (tabpanels)
  139.               tabpanels.selectedPanel = val;
  140.           }
  141.           return val;
  142.         ]]>
  143.         </setter>
  144.       </property>
  145.  
  146.       <method name="handleEvent">
  147.         <parameter name="event"/>
  148.         <body>
  149.         <![CDATA[
  150.           if (!event.isTrusted) {
  151.             // Don't let untrusted events mess with tabs.
  152.             return;
  153.           }
  154.  
  155.           switch (event.keyCode) {
  156.             case event.DOM_VK_TAB:
  157.               if (event.ctrlKey && !event.altKey && !event.metaKey)
  158.                 if (this.tabs && this.handleCtrlTab) {
  159.                   this.tabs.advanceSelectedTab(event.shiftKey ? -1 : 1, true);
  160.                   event.stopPropagation();
  161.                   event.preventDefault();
  162.                 }
  163.               break;
  164.             case event.DOM_VK_PAGE_UP:
  165.               if (event.ctrlKey && !event.shiftKey && !event.altKey && !event.metaKey)
  166.                 if (this.tabs && this.handleCtrlPageUpDown) {
  167.                   this.tabs.advanceSelectedTab(-1, true);
  168.                   event.stopPropagation();
  169.                   event.preventDefault();
  170.                 }
  171.               break;
  172.             case event.DOM_VK_PAGE_DOWN:
  173.               if (event.ctrlKey && !event.shiftKey && !event.altKey && !event.metaKey)
  174.                 if (this.tabs && this.handleCtrlPageUpDown) {
  175.                   this.tabs.advanceSelectedTab(1, true);
  176.                   event.stopPropagation();
  177.                   event.preventDefault();
  178.                 }
  179.               break;
  180.             case event.DOM_VK_LEFT:
  181.               if (event.metaKey && event.altKey && !event.shiftKey && !event.ctrlKey)
  182.                 if (this.tabs && this._handleMetaAltArrows) {
  183.                   var offset = window.getComputedStyle(this, "")
  184.                                      .direction == "ltr" ? -1 : 1;
  185.                   this.tabs.advanceSelectedTab(offset, true);
  186.                   event.stopPropagation();
  187.                   event.preventDefault();
  188.                 }
  189.               break;
  190.             case event.DOM_VK_RIGHT:
  191.               if (event.metaKey && event.altKey && !event.shiftKey && !event.ctrlKey)
  192.                 if (this.tabs && this._handleMetaAltArrows) {
  193.                   var offset = window.getComputedStyle(this, "")
  194.                                      .direction == "ltr" ? 1 : -1;
  195.                   this.tabs.advanceSelectedTab(offset, true);
  196.                   event.stopPropagation();
  197.                   event.preventDefault();
  198.                 }
  199.               break;
  200.           }
  201.         ]]>
  202.         </body>
  203.       </method>
  204.  
  205.       <field name="_eventNode">this</field>
  206.  
  207.       <property name="eventNode" onget="return this._eventNode;">
  208.         <setter>
  209.           <![CDATA[
  210.             if (val != this._eventNode) {
  211.               val.addEventListener("keypress", this, false);
  212.               this._eventNode.removeEventListener("keypress", this, false);
  213.               this._eventNode = val;
  214.             }
  215.             return val;
  216.           ]]>
  217.         </setter>
  218.       </property>
  219.  
  220.       <constructor>
  221.         switch (this.getAttribute("eventnode")) {
  222.           case "parent": this._eventNode = this.parentNode; break;
  223.           case "window": this._eventNode = window; break;
  224.           case "document": this._eventNode = document; break;
  225.         }
  226.         this._eventNode.addEventListener("keypress", this, false);
  227.       </constructor>
  228.  
  229.       <destructor>
  230.         this._eventNode.removeEventListener("keypress", this, false);
  231.       </destructor>
  232.     </implementation>
  233.   </binding>
  234.  
  235.   <binding id="tabs"
  236.            extends="chrome://global/content/bindings/general.xml#basecontrol">
  237.     <resources>
  238.       <stylesheet src="chrome://global/skin/tabbox.css"/>
  239.     </resources>
  240.  
  241.     <content>
  242.       <xul:spacer class="tabs-left"/>
  243.       <children/>
  244.       <xul:spacer class="tabs-right" flex="1"/>
  245.     </content>
  246.     
  247.     <implementation implements="nsIDOMXULSelectControlElement, nsIAccessibleProvider">
  248.       <constructor>
  249.       <![CDATA[
  250.         // first and last tabs need to be able to have unique styles
  251.         // and also need to select first tab on startup.
  252.         if (this.firstChild)
  253.           this.firstChild.setAttribute("first-tab", "true");
  254.         if (this.lastChild)
  255.           this.lastChild.setAttribute("last-tab", "true");
  256.  
  257.         var o = this.getAttribute("orient");
  258.         if (!o)
  259.           this.setAttribute("orient", "horizontal");
  260.  
  261.         for (var parent = this.parentNode; parent; parent = parent.parentNode) {
  262.           if (parent.localName == "tabbox" && parent.hasAttribute("selectedIndex")) {
  263.             var selectedIndex = parseInt(parent.getAttribute("selectedIndex"));
  264.             this.selectedIndex = selectedIndex > 0 ? selectedIndex : 0;
  265.             return;
  266.           }
  267.         }
  268.  
  269.         var children = this.childNodes;
  270.         var length = children.length;
  271.         for (var i = 0; i < length; i++) {
  272.           if (children[i].getAttribute("selected") == "true") {
  273.             this.selectedIndex = i;
  274.             return;
  275.           }
  276.         }
  277.  
  278.         var value = this.value;
  279.         if (value)
  280.           this.value = value;
  281.         else
  282.           this.selectedIndex = 0;
  283.       ]]>
  284.       </constructor>
  285.       
  286.       <property name="accessibleType" readonly="true">
  287.         <getter>
  288.           <![CDATA[
  289.             return Components.interfaces.nsIAccessibleProvider.XULTabs;
  290.           ]]>
  291.         </getter>
  292.       </property>
  293.  
  294.       <property name="itemCount" readonly="true"
  295.                 onget="return this.childNodes.length"/>
  296.  
  297.       <property name="value" onget="return this.getAttribute('value');">
  298.         <setter>
  299.           <![CDATA[
  300.             this.setAttribute("value", val);
  301.             var children = this.childNodes;
  302.             for (var c = children.length - 1; c >= 0; c--) {
  303.               if (children[c].value == val) {
  304.                 this.selectedIndex = c;
  305.                 break;
  306.               }
  307.             }
  308.             return val;
  309.           ]]>
  310.         </setter>
  311.       </property>
  312.  
  313.       <property name="selectedIndex">
  314.         <getter>
  315.         <![CDATA[
  316.           const tabs = this.childNodes;
  317.           for (var i = 0; i < tabs.length; i++) {
  318.             if (tabs[i].selected)
  319.               return i;
  320.           }
  321.           return -1;
  322.         ]]>
  323.         </getter>
  324.         
  325.         <setter>
  326.         <![CDATA[
  327.           var tab = this.getItemAtIndex(val);
  328.           if (tab) {
  329.             var alreadySelected = tab.selected;
  330.  
  331.             Array.forEach(this.childNodes, function (aTab) {
  332.               if (aTab.selected && aTab != tab)
  333.                 aTab._selected = false;
  334.             });
  335.             tab._selected = true;
  336.  
  337.             this.setAttribute("value", tab.value);
  338.  
  339.             for (var parent = this.parentNode; parent; parent = parent.parentNode) {
  340.               if (parent.localName == 'tabbox') {
  341.                 parent.setAttribute("selectedIndex", val);
  342.                 var tabpanels = parent.tabpanels;
  343.                 // This will cause an onselect event to fire for the tabpanel element.
  344.                 if (tabpanels) {
  345.                   // find an id 
  346.                   var linkedPanelId = tab.linkedPanel;
  347.                   var linkedPanel = linkedPanelId ? document.getElementById(linkedPanelId) : null;
  348.                   if (linkedPanel)
  349.                     tabpanels.selectedPanel = linkedPanel;
  350.                   else
  351.                     tabpanels.selectedIndex = val;
  352.                 }
  353.                 break;
  354.               }
  355.             }
  356.  
  357.             if (!alreadySelected) {
  358.               // Fire an onselect event for the tabs element.
  359.               var event = document.createEvent('Events');
  360.               event.initEvent('select', true, true);
  361.               this.dispatchEvent(event);
  362.             }
  363.           }
  364.           return val;
  365.         ]]>
  366.         </setter>
  367.       </property>
  368.  
  369.       <property name="selectedItem">
  370.         <getter>
  371.         <![CDATA[
  372.           const tabs = this.childNodes;
  373.           for (var i = 0; i < tabs.length; i++) {
  374.             if (tabs[i].selected)
  375.               return tabs[i];
  376.           }
  377.           return null;
  378.         ]]>
  379.         </getter>
  380.  
  381.         <setter>
  382.         <![CDATA[
  383.           if (val && !val.selected)
  384.             // The selectedIndex setter ignores invalid values
  385.             // such as -1 if |val| isn't one of our child nodes.
  386.             this.selectedIndex = this.getIndexOfItem(val);
  387.           return val;
  388.         ]]>
  389.         </setter>
  390.       </property>
  391.  
  392.       <method name="getIndexOfItem">
  393.         <parameter name="item"/>
  394.         <body>
  395.         <![CDATA[
  396.           return Array.indexOf(this.childNodes, item);
  397.         ]]>
  398.         </body>
  399.       </method>
  400.  
  401.       <method name="getItemAtIndex">
  402.         <parameter name="index"/>
  403.         <body>
  404.         <![CDATA[
  405.           return this.childNodes.item(index);
  406.         ]]>
  407.         </body>
  408.       </method>
  409.  
  410.       <method name="_selectNewTab">
  411.         <parameter name="aNewTab"/>
  412.         <parameter name="aFallbackDir"/>
  413.         <parameter name="aWrap"/>
  414.         <body>
  415.         <![CDATA[
  416.           var requestedTab = aNewTab;
  417.           while (aNewTab.hidden || aNewTab.disabled) {
  418.             aNewTab = aFallbackDir == -1 ? aNewTab.previousSibling : aNewTab.nextSibling;
  419.             if (!aNewTab && aWrap)
  420.               aNewTab = aFallbackDir == -1 ? this.childNodes[this.childNodes.length - 1] :
  421.                                              this.childNodes[0];
  422.             if (aNewTab == requestedTab)
  423.               return;
  424.           }
  425.  
  426.           var isTabFocused = false;
  427.           try {
  428.             isTabFocused =
  429.               (document.commandDispatcher.focusedElement == this.selectedItem);
  430.           } catch (e) {}
  431.           this.selectedItem = aNewTab;
  432.           if (isTabFocused) {
  433.             aNewTab.focus();
  434.           }
  435.           else if (this.getAttribute("setfocus") != "false") {
  436.             document.commandDispatcher.advanceFocusIntoSubtree(aNewTab);
  437.             
  438.             // Make sure that the focus doesn't move outside the tabbox
  439.             for (var parent = this.parentNode; parent; parent = parent.parentNode) {
  440.               if (parent.localName == "tabbox") {
  441.                 try {
  442.                   var el = document.commandDispatcher.focusedElement;
  443.                   while (el && el != parent)
  444.                     el = el.parentNode;
  445.                   if (el != parent)
  446.                     aNewTab.focus();
  447.                 } catch(e) {
  448.                 }
  449.                 break;
  450.               }
  451.             }
  452.           }
  453.         ]]>
  454.         </body>
  455.       </method>
  456.  
  457.       <method name="advanceSelectedTab">
  458.         <parameter name="aDir"/>
  459.         <parameter name="aWrap"/>
  460.         <body>
  461.         <![CDATA[
  462.           var startTab = this.selectedItem;
  463.           var next = startTab[aDir == -1 ? "previousSibling" : "nextSibling"];
  464.           if (!next && aWrap) {
  465.             next = aDir == -1 ? this.childNodes[this.childNodes.length - 1] :
  466.                                 this.childNodes[0];
  467.           }
  468.           if (next && next != startTab) {
  469.             this._selectNewTab(next, aDir, aWrap);
  470.           }
  471.         ]]>
  472.         </body>
  473.       </method>
  474.  
  475.       <method name="appendItem">
  476.         <parameter name="label"/>
  477.         <parameter name="value"/>
  478.         <body>
  479.         <![CDATA[
  480.           var XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
  481.           var tab = document.createElementNS(XULNS, "tab");
  482.           tab.setAttribute("label", label);
  483.           tab.setAttribute("value", value);
  484.           this.appendChild(tab);
  485.           return tab;
  486.         ]]>
  487.         </body>
  488.       </method>
  489.       
  490.       <method name="insertItemAt">
  491.         <parameter name="index"/>
  492.         <parameter name="label"/>
  493.         <parameter name="value"/>
  494.         <body>
  495.         <![CDATA[
  496.           var XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
  497.           var tab = document.createElementNS(XULNS, "tab");
  498.           tab.setAttribute("label", label);
  499.           tab.setAttribute("value", value);
  500.           var before = this.getItemAtIndex(index);
  501.           if (before)
  502.             this.insertBefore(tab, before);
  503.           else
  504.             this.appendChild(tab);
  505.           return tab;
  506.         ]]>
  507.         </body>
  508.       </method>
  509.  
  510.       <method name="removeItemAt">
  511.         <parameter name="index"/>
  512.         <body>
  513.         <![CDATA[
  514.           var remove = this.getItemAtIndex(index);
  515.           if (remove)
  516.             this.removeChild(remove);
  517.           return remove;
  518.         ]]>
  519.         </body>
  520.       </method>
  521.     </implementation>
  522.   </binding>
  523.  
  524.   <!-- 
  525.   XXXben - this looks like something added specifically for tabbrowser.
  526.            if it turns out no one uses this that can't easily be evangelized to
  527.            use their own roll-your-own binding, then we should get rid of this
  528.            to tighten up the toolkit api. This binding made obsolete in Firefox
  529.            by 308396. 
  530.   -->
  531.   <binding id="tabs-closebutton" 
  532.            extends="chrome://global/content/bindings/tabbox.xml#tabs">
  533.     <content>
  534.       <xul:hbox flex="1" style="min-width: 1px; overflow: -moz-hidden-unscrollable;">
  535.         <children/>
  536.         <xul:spacer class="tabs-right" flex="1"/>
  537.       </xul:hbox>
  538.       <xul:stack>
  539.         <xul:spacer class="tabs-right"/>
  540.         <xul:hbox class="tabs-closebutton-box" align="center" pack="end">
  541.           <xul:toolbarbutton ondblclick="event.stopPropagation();" class="tabs-closebutton close-button" xbl:inherits="disabled=disableclose,oncommand=onclosetab"/>
  542.         </xul:hbox>
  543.       </xul:stack>
  544.     </content>
  545.   </binding>
  546.  
  547.   <binding id="tabpanels"
  548.            extends="chrome://global/content/bindings/tabbox.xml#tab-base">
  549.     <implementation>
  550.  
  551.       <field name="_selectedPanel">this.childNodes.item(this.selectedIndex)</field>
  552.  
  553.       <property name="selectedIndex">
  554.         <getter>
  555.         <![CDATA[
  556.           var indexStr = this.getAttribute("selectedIndex");
  557.           return indexStr ? parseInt(indexStr) : -1;
  558.         ]]>
  559.         </getter>
  560.  
  561.         <setter>
  562.         <![CDATA[
  563.           if (val < 0 || val >= this.childNodes.length)
  564.             return val;
  565.           var panel = this._selectedPanel;
  566.           this._selectedPanel = this.childNodes[val];
  567.           this.setAttribute("selectedIndex", val);
  568.           if (this._selectedPanel != panel) {
  569.             var event = document.createEvent("Events");
  570.             event.initEvent("select", true, true);
  571.             this.dispatchEvent(event);
  572.           }
  573.           return val;
  574.         ]]>
  575.         </setter>
  576.       </property>
  577.  
  578.       <property name="selectedPanel">
  579.         <getter>
  580.           <![CDATA[
  581.             return this._selectedPanel;
  582.           ]]>
  583.         </getter>
  584.  
  585.         <setter>
  586.           <![CDATA[
  587.             var selectedIndex = -1;
  588.             for (var panel = val; panel != null; panel = panel.previousSibling)
  589.               ++selectedIndex;
  590.             this.selectedIndex = selectedIndex;
  591.             return val;
  592.           ]]>
  593.         </setter>
  594.       </property>
  595.     </implementation>
  596.   </binding>
  597.  
  598.   <binding id="tab" display="xul:button"
  599.            extends="chrome://global/content/bindings/general.xml#control-item">
  600.     <resources>
  601.       <stylesheet src="chrome://global/skin/tabbox.css"/>
  602.     </resources>
  603.  
  604.     <content chromedir="&locale.dir;">
  605.       <xul:hbox class="tab-middle box-inherit" xbl:inherits="align,dir,pack,orient,selected" flex="1">
  606.         <xul:image class="tab-icon" xbl:inherits="validate,src=image"/>
  607.         <xul:label class="tab-text" xbl:inherits="value=label,accesskey,crop,disabled" flex="1"/>
  608.       </xul:hbox>
  609.     </content>
  610.  
  611.     <implementation implements="nsIDOMXULSelectControlItemElement, nsIAccessibleProvider">
  612.       <property name="accessibleType" readonly="true">
  613.         <getter>
  614.           <![CDATA[
  615.             return Components.interfaces.nsIAccessibleProvider.XULTab;
  616.           ]]>
  617.         </getter>
  618.       </property>
  619.  
  620.       <property name="control" readonly="true">
  621.         <getter>
  622.           <![CDATA[
  623.             var parent = this.parentNode;
  624.             if (parent instanceof Components.interfaces.nsIDOMXULSelectControlElement)
  625.               return parent;
  626.             return null;
  627.           ]]>
  628.         </getter>
  629.       </property>
  630.  
  631.       <property name="selected" readonly="true"
  632.                 onget="return this.getAttribute('selected') == 'true';"/>
  633.  
  634.       <property name="_selected">
  635.         <setter>
  636.           <![CDATA[
  637.           this.setAttribute("selected", val);
  638.           if (this.previousSibling && this.previousSibling.localName == "tab") {
  639.             if (val)
  640.               this.previousSibling.setAttribute("beforeselected", val);
  641.             else
  642.               this.previousSibling.removeAttribute("beforeselected");
  643.             this.removeAttribute("first-tab");
  644.           }
  645.           else
  646.             this.setAttribute("first-tab", "true");
  647.  
  648.           if (this.nextSibling && this.nextSibling.localName == "tab") {
  649.             if (val)
  650.               this.nextSibling.setAttribute("afterselected", val);
  651.             else
  652.               this.nextSibling.removeAttribute("afterselected");
  653.             this.removeAttribute("last-tab");
  654.           }
  655.           else
  656.             this.setAttribute("last-tab", "true");
  657.           return val;
  658.         ]]>
  659.         </setter>
  660.       </property>
  661.  
  662.       <property name="linkedPanel" onget="return this.getAttribute('linkedpanel')"
  663.                                    onset="this.setAttribute('linkedpanel', val); return val;"/>
  664.  
  665.       <field name="arrowKeysShouldWrap" readonly="true">
  666.         false
  667.       </field>    
  668.     </implementation>
  669.  
  670.     <handlers>
  671.       <handler event="mousedown" button="0">
  672.       <![CDATA[
  673.         if (this.disabled)
  674.           return;
  675.  
  676.         if (this != this.parentNode.selectedItem) { // Not selected yet
  677.           // Select new tab after short delay so that PostHandleEvent() doesn't see
  678.           // the tab as selected yet, otherwise it will focus the tab for us --
  679.           // the CSS for tab has -moz-user-focus: normal only for selected="true".
  680.           function setTab(tab) {
  681.             tab.parentNode._selectNewTab(tab);
  682.           }
  683.           setTimeout(setTab, 0, this);
  684.         }
  685.         // Otherwise this tab is already selected and we will fall
  686.         // through to mousedown behavior which sets focus on the current tab,
  687.         // Only a click on an already selected tab should focus the tab itself.
  688.       ]]>
  689.       </handler>
  690.  
  691.       <handler event="keypress" keycode="VK_LEFT">
  692.       <![CDATA[
  693.         var direction = window.getComputedStyle(this.parentNode, null).direction;
  694.         this.parentNode.advanceSelectedTab(direction == 'ltr' ? -1 : 1, this.arrowKeysShouldWrap);
  695.       ]]>
  696.       </handler>
  697.  
  698.       <handler event="keypress" keycode="VK_RIGHT">
  699.       <![CDATA[
  700.         var direction = window.getComputedStyle(this.parentNode, null).direction;
  701.         this.parentNode.advanceSelectedTab(direction == 'ltr' ? 1 : -1, this.arrowKeysShouldWrap);
  702.       ]]>
  703.       </handler>
  704.  
  705.       <handler event="keypress" keycode="VK_UP">
  706.       <![CDATA[
  707.         this.parentNode.advanceSelectedTab(-1, this.arrowKeysShouldWrap);
  708.       ]]>
  709.       </handler>
  710.  
  711.       <handler event="keypress" keycode="VK_DOWN">
  712.       <![CDATA[
  713.         this.parentNode.advanceSelectedTab(1, this.arrowKeysShouldWrap);
  714.       ]]>
  715.       </handler>
  716.  
  717.       <handler event="keypress" keycode="VK_HOME">
  718.       <![CDATA[
  719.         this.parentNode._selectNewTab(this.parentNode.childNodes[0]);
  720.       ]]>
  721.       </handler>
  722.  
  723.       <handler event="keypress" keycode="VK_END">
  724.       <![CDATA[
  725.         var tabs = this.parentNode.childNodes;
  726.         this.parentNode._selectNewTab(tabs[tabs.length - 1], -1);
  727.       ]]>
  728.       </handler>
  729.     </handlers>
  730.   </binding>
  731.  
  732. </bindings>
  733.  
  734.